import 'dart:async';
import 'dart:convert';

import 'package:shared_preferences/shared_preferences.dart';
import 'package:synchronized/synchronized.dart';


/// main.dart 初始化
/// await EMPDataPersisten.getInstance();

class EMPDataPersisten {
  static EMPDataPersisten? _singleton;///单利
  static SharedPreferences? _prefs;///持久化存储数据的类，存储应用程序的配置信息、用户偏好设置、登录状态等简单的数据。
  static Lock _lock = Lock();///确保单例实例的线程安全性

  static Future<EMPDataPersisten?> getInstance() async {
    if (_singleton == null) {
      await _lock.synchronized(() async {
        if (_singleton == null) {
          /// 保持本地实例直到完全初始化。
          var singleton = EMPDataPersisten._();
          await singleton._init();
          _singleton = singleton;
        }
      });
    }
    return _singleton;
  }

  EMPDataPersisten._();///私有的命名构造函数 _()，用于创建类的实例

  Future _init() async {///async异步方法
    _prefs = await SharedPreferences.getInstance();///await等待结果
  }

  /// 将对象以JSON字符串的形式存储到SharedPreferences中。
  static Future<bool>? putObject(String key, Object value) {
    return _prefs?.setString(key, json.encode(value));
  }

  /// 从SharedPreferences中获取JSON字符串并解析为指定类型的对象。
  static T? getObj<T>(String key, T f(Map v), {T? defValue}) {
    Map? map = getObject(key);
    return map == null ? defValue : f(map);
  }

  /// SharedPreferences中获取JSON字符串并解析为Map对象。
  static Map? getObject(String key) {
    String? _data = _prefs?.getString(key);
    return (_data == null || _data.isEmpty) ? null : json.decode(_data);
  }

  /// 将对象列表以JSON字符串的形式存储到SharedPreferences中。
  static Future<bool>? putObjectList(String key, List<Object> list) {
    List<String>? _dataList = list.map((value) {
      return json.encode(value);
    }).toList();
    return _prefs?.setStringList(key, _dataList);
  }

  /// 从SharedPreferences中获取JSON字符串列表并解析为指定类型的对象列表。
  static List<T>? getObjList<T>(String key, T f(Map v),
      {List<T>? defValue = const []}) {
    List<Map>? dataList = getObjectList(key);
    List<T>? list = dataList?.map((value) {
      return f(value);
    }).toList();
    return list ?? defValue;
  }

  /// 从SharedPreferences中获取JSON字符串列表并解析为Map对象列表。
  static List<Map>? getObjectList(String key) {
    List<String>? dataLis = _prefs?.getStringList(key);
    return dataLis?.map((value) {
      Map _dataMap = json.decode(value);
      return _dataMap;
    }).toList();
  }

  /// 获取字符串类型数据。如果指定的键不存在，则返回默认值（默认为''）。
  static String? getString(String key, {String? defValue = ''}) {
    return _prefs?.getString(key) ?? defValue;
  }

  /// 将字符串类型的数据存储到SharedPreferences中
  static Future<bool>? putString(String key, String value) {
    return _prefs?.setString(key, value);
  }

  /// 获取布尔类型数据。如果指定的键不存在，则返回默认值（默认为false）。
  static bool? getBool(String key, {bool? defValue = false}) {
    return _prefs?.getBool(key) ?? defValue;
  }

  /// 将布尔类型数据存储到SharedPreferences中。
  static Future<bool>? putBool(String key, bool value) {
    return _prefs?.setBool(key, value);
  }

  /// 获取整数类型数据。如果指定的键不存在，则返回默认值（默认为0）。
  static int? getInt(String key, {int? defValue = 0}) {
    return _prefs?.getInt(key) ?? defValue;
  }

  /// 将整数类型数据存储到SharedPreferences中。
  static Future<bool>? putInt(String key, int value) {
    return _prefs?.setInt(key, value);
  }

  /// 获取浮点数类型数据。如果指定的键不存在，则返回默认值（默认为0.0）。
  static double? getDouble(String key, {double? defValue = 0.0}) {
    return _prefs?.getDouble(key) ?? defValue;
  }

  /// 将浮点数类型数据存储到SharedPreferences中。
  static Future<bool>? putDouble(String key, double value) {
    return _prefs?.setDouble(key, value);
  }

  /// 获取字符串列表类型数据。如果指定的键不存在，则返回默认值（默认为空列表）。
  static List<String>? getStringList(String key,
      {List<String>? defValue = const []}) {
    return _prefs?.getStringList(key) ?? defValue;
  }

  /// 将字符串列表类型数据存储到SharedPreferences中。
  static Future<bool>? putStringList(String key, List<String> value) {
    return _prefs?.setStringList(key, value);
  }

  /// 获取键为key的动态类型数据。如果键不存在，则返回默认值defValue（默认为null）。
  static dynamic getDynamic(String key, {Object? defValue}) {
    return _prefs?.get(key) ?? defValue;
  }

  /// 检查SharedPreferences中是否存在指定键key
  static bool? haveKey(String key) {
    return _prefs?.getKeys().contains(key);
  }

  /// 检查SharedPreferences中是否包含指定键key。
  static bool? containsKey(String key) {
    return _prefs?.containsKey(key);
  }

  /// 获取SharedPreferences中所有键的集合。
  static Set<String>? getKeys() {
    return _prefs?.getKeys();
  }

  /// 删除SharedPreferences中指定键key的数据。
  /// 返回的是一个布尔值的Future对象，异步操作，可以使用await关键字来等待结果。这个方法适用于需要异步处理
  static Future<bool>? remove(String key) {
    return _prefs?.remove(key);
  }

  /// 用于清除SharedPreferences中所有的键值对，并返回一个表示清除操作是否成功的Future<bool>对象。
  /// 如果清除成功，返回true；否则返回false。
  static Future<bool>? clear() {
    return _prefs?.clear();
  }

  /// 这个方法用于取最新的SharedPreferences值。
  static Future<void>? reload() {
    return _prefs?.reload();
  }

  ///用于检查SharedPreferences是否已经被初始化。
  ///如果SharedPreferences对象不为null，则说明已经初始化完成。
  static bool isInitialized() {
    return _prefs != null;
  }

  /// 用于获取当前的SharedPreferences对象。
  /// 如果SharedPreferences对象已经被初始化，就返回该对象；否则返回null。
  static SharedPreferences? getSp() {
    return _prefs;
  }
}
